using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Drawing.Imaging;
using System.Collections;
using System.Drawing.Drawing2D;
using System.Runtime.InteropServices;
using System.Web;
using System.Net;
namespace OF.Utility
{
    public class PictureUtility
    {

        #region 通用方法

        #region 从字节数组中得到图片
        public static Image GetImgFromBytes(byte[] buffer)
        {
            try
            {
                MemoryStream ms = new MemoryStream(buffer);
                System.Drawing.Image img = Bitmap.FromStream(ms);
                return img;
            }
            catch
            {
                return null;
            }
        }
        #endregion

        #region 获取图形编码信息
        private static ImageCodecInfo GetCodecInfo(string mimeType)
        {
            ImageCodecInfo[] CodecInfo = ImageCodecInfo.GetImageEncoders();
            foreach (ImageCodecInfo ici in CodecInfo)
            {
                if (ici.MimeType == mimeType) return ici;
            }
            return null;
        }
        #endregion

        #region 缩略图
        /// <summary>
        /// 生成指定了最大宽度的缩略图
        /// </summary>
        /// <param name="originalImagePath">源图路径（物理路径）</param>
        /// <param name="maxWidth">缩略图最大边长</param>
        public static void MakeThumbnail(System.Drawing.Image originalImage, Int32 maxWidth, string originalImagePath)
        {

            //String tempFile = originalImagePath + "Temp";

            ////原图文件名改为临时文件名
            ////System.IO.File.Move(originalImagePath, tempFile);

            //System.Drawing.Image originalImage = System.Drawing.Image.FromStream(originalImagePath);
            Int32 towidth = originalImage.Width;
            Int32 toheight = originalImage.Height;
            Int32 x = 0;
            Int32 y = 0;
            Int32 ow = originalImage.Width;
            Int32 oh = originalImage.Height;

            //指定宽，高按比例
            //只有当原图宽度大于指定最大宽度时，才进行缩放
            if (originalImage.Width > maxWidth)
            {
                towidth = maxWidth;
                toheight = originalImage.Height * maxWidth / originalImage.Width;
            }

            //Utility.LogInfo("Make Thunbnail", "mode = " + mode.ToString() + ", width = " + width + ", height = " + height + ", towidth = " + towidth + ", toheight = " + toheight + ", x = " + x + ", y = " + y + ", ow = " + ow + ", oh = " + oh);

            //新建一个bmp图片
            System.Drawing.Image bitmap = new System.Drawing.Bitmap(towidth, toheight);

            //Image im = AddWaterMark(bitmap, Bitmap.FromFile(SiteUtility.GetServerPath(SiteUtility.GetAppSettings("shuiyin"))), 1);

            //新建一个画板
            System.Drawing.Graphics g = System.Drawing.Graphics.FromImage(bitmap);

            //设置高质量插值法
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;

            //设置高质量,低速度呈现平滑程度
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            //清空画布并以透明背景色填充
            g.Clear(System.Drawing.Color.Transparent);

            //在指定位置并且按指定大小绘制原图片的指定部分
            g.DrawImage(originalImage,
                new System.Drawing.Rectangle(0, 0, towidth, toheight),
                new System.Drawing.Rectangle(x, y, ow, oh),
                System.Drawing.GraphicsUnit.Pixel);

            try
            {
                //以jpg格式保存缩略图
                bitmap.Save(originalImagePath, System.Drawing.Imaging.ImageFormat.Jpeg);
            }
            catch (System.Exception e)
            {
                //this.SendFileUploadResponse(1, true, "", "", e.ToString());
            }
            finally
            {
                originalImage.Dispose();
                bitmap.Dispose();
                g.Dispose();

                //删除临时文件
                //System.IO.File.Delete(tempFile);
            }

        }
        #endregion

        #region 图片加水印
        /// <summary>
        /// 图片加水印
        /// </summary>
        /// <param name="Source">源图片</param>
        /// <param name="Stamp">水印图片</param>
        /// <param name="Position">
        /// 水印位置
        /// 1：右下角
        /// 2：左下角
        /// 3：右上角
        /// 4：左上角
        /// 5：中间
        /// </param>
        /// <returns></returns>
        public static Image AddWaterMark(Image Source, Image Stamp, int Position)
        {
            Bitmap bm = new Bitmap(Source.Width, Source.Height);

            Graphics g = Graphics.FromImage(bm);
            g.DrawImage(Source, new Point(0, 0));

            //设置图像的透明度
            float[][] ptsArray ={
                                    new float[] {1, 0, 0, 0, 0},
                                    new float[] {0, 1, 0, 0, 0},
                                    new float[] {0, 0, 1, 0, 0},
                                    new float[] {0, 0, 0, 0.4F, 0}, //注意：在此处设图象的透明度
                                    new float[] {0, 0, 0, 0, 1}};

            ColorMatrix clrMatrix = new ColorMatrix(ptsArray);
            ImageAttributes imgAttributes = new ImageAttributes();

            imgAttributes.SetColorMatrix(clrMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

            //画图像
            Rectangle rect = new Rectangle();
            rect.Height = Stamp.Height;
            rect.Width = Stamp.Width;
            switch (Position)
            {
                default:
                case 1:
                    rect.X = Source.Width - Stamp.Width;
                    rect.Y = Source.Height - Stamp.Height;
                    break;
                case 2:
                    rect.X = 0;
                    rect.Y = Source.Height - Stamp.Height;
                    break;
                case 3:
                    rect.X = Source.Width - Stamp.Width;
                    rect.Y = 0;
                    break;
                case 4:
                    rect.X = 0;
                    rect.Y = 0;
                    break;
                case 5:
                    rect.X = (Source.Width - Stamp.Width) / 2;
                    rect.Y = (Source.Height - Stamp.Height) / 2;
                    break;
            }
            g.DrawImage(Stamp, rect, 0, 0, Stamp.Width, Stamp.Height, GraphicsUnit.Pixel, imgAttributes);

            g.Dispose();
            return bm;
        }
        #endregion

        #region 添加文字水印
        /// <summary>         
        /// 添加文字水印         
        /// </summary>         
        /// <param name="text">水印文字</param>         
        /// <param name="file">图片文件</param>         
        public static void AttachText(string text, string file, string path)
        {
            if (string.IsNullOrEmpty(text))
            {
                return;
            }
            if (!File.Exists(file))
            {
                return;
            }
            FileInfo oFile = new FileInfo(file);
            string strTempFile = Path.Combine(oFile.DirectoryName, Guid.NewGuid().ToString() + oFile.Extension);
            oFile.CopyTo(strTempFile);
            Image img = Image.FromFile(strTempFile);
            ImageFormat thisFormat = img.RawFormat;
            int nHeight = img.Height;
            int nWidth = img.Width;
            Bitmap outBmp = new Bitmap(nWidth, nHeight);
            Graphics g = Graphics.FromImage(outBmp);
            g.Clear(Color.White);
            // 设置画布的描绘质量        
            g.CompositingQuality = CompositingQuality.HighQuality;
            g.SmoothingMode = SmoothingMode.HighQuality;
            g.InterpolationMode = InterpolationMode.HighQualityBicubic;
            g.DrawImage(img, new Rectangle(0, 0, nWidth, nHeight), 0, 0, nWidth, nHeight, GraphicsUnit.Pixel);
            int[] sizes = new int[] { 16, 14, 12, 10, 8, 6, 4 };
            Font crFont = null;
            SizeF crSize = new SizeF();
            //通过循环这个数组，来选用不同的字体大小   
            //如果它的大小小于图像的宽度，就选用这个大小的字体     
            for (int i = 0; i < 7; i++)
            {
                //设置字体，这里是用arial，黑体       
                crFont = new Font("arial", sizes[i], FontStyle.Bold);
                //Measure the Copyright string in this Font             
                crSize = g.MeasureString(text, crFont);
                if ((ushort)crSize.Width < (ushort)nWidth)
                { break; }
            }
            //因为图片的高度可能不尽相同, 所以定义了       
            //从图片底部算起预留了5%的空间     
            int yPixlesFromBottom = (int)(nHeight * .08);
            //现在使用版权信息字符串的高度来确定要绘制的图像的字符串的y坐标    
            float yPosFromBottom = ((nHeight - yPixlesFromBottom) - (crSize.Height / 2));
            //计算x坐标          
            float xCenterOfImg = (nWidth / 2);
            //把文本布局设置为居中          
            StringFormat StrFormat = new StringFormat();

            StrFormat.Alignment = StringAlignment.Center;
            //通过Brush来设置黑色半透明      
            SolidBrush semiTransBrush2 = new SolidBrush(Color.FromArgb(153, 0, 0, 0));
            //绘制版权字符串           
            g.DrawString(text,             //版权字符串文本            
                crFont,                             //字体           
                semiTransBrush2,                           //Brush        
                new PointF(xCenterOfImg + 1, yPosFromBottom + 1),  //位置     
                StrFormat);              //设置成白色半透明          
            SolidBrush semiTransBrush = new SolidBrush(Color.FromArgb(153, 255, 255, 255));
            //第二次绘制版权字符串来创建阴影效果           
            //记住移动文本的位置1像素           
            g.DrawString(text,                 //版权文本     
                crFont,                                   //字体 
                semiTransBrush,                           //Brush    
                new PointF(xCenterOfImg, yPosFromBottom),  //位置     
                StrFormat);
            g.Dispose();              // 以下代码为保存图片时，设置压缩质量         
            EncoderParameters encoderParams = new EncoderParameters();
            long[] quality = new long[1];
            quality[0] = 100;
            EncoderParameter encoderParam = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
            encoderParams.Param[0] = encoderParam;              //获得包含有关内置图像编码解码器的信息的ImageCodecInfo 对象。
            ImageCodecInfo[] arrayICI = ImageCodecInfo.GetImageEncoders();
            ImageCodecInfo jpegICI = null;
            for (int x = 0; x < arrayICI.Length; x++)
            {
                if (arrayICI[x].FormatDescription.Equals("JPEG"))
                {
                    jpegICI = arrayICI[x];//设置JPEG编码          
                    break;
                }
            }
            if (jpegICI != null)
            { outBmp.Save(file, jpegICI, encoderParams); }
            else { outBmp.Save(file, thisFormat); }
            img.Dispose();
            outBmp.Dispose();
            File.Delete(strTempFile);
        }
        #endregion

        #endregion

        #region 从大图中截取一部分图片
        /// <summary>
        /// 从大图中截取一部分图片
        /// </summary>
        /// <param name="fromImagePath">来源图片地址</param>        
        /// <param name="offsetX">从偏移X坐标位置开始截取</param>
        /// <param name="offsetY">从偏移Y坐标位置开始截取</param>
        /// <param name="toImagePath">保存图片地址</param>
        /// <param name="width">保存图片的宽度</param>
        /// <param name="height">保存图片的高度</param>
        /// <returns></returns>
        public static void CaptureImage(string fromImagePath, int offsetX, int offsetY, string toImagePath, int width, int height)
        {
            //原图片文件
            Image fromImage = Image.FromFile(fromImagePath);
            //创建新图位图
            Bitmap bitmap = new Bitmap(width, height);
            //创建作图区域
            Graphics graphic = Graphics.FromImage(bitmap);
            //截取原图相应区域写入作图区
            graphic.DrawImage(fromImage, 0, 0, new Rectangle(offsetX, offsetY, width, height), GraphicsUnit.Pixel);
            //从作图区生成新图
            Image saveImage = Image.FromHbitmap(bitmap.GetHbitmap());
            //保存图片
            saveImage.Save(toImagePath, ImageFormat.Jpeg);
            //释放资源   
            saveImage.Dispose();
            graphic.Dispose();
            bitmap.Dispose();
        }
        #endregion

        #region JPEG图片操作
        /// <summary>
        /// JPEG图片压缩
        /// </summary>
        /// <param name="ScaleImage">源图片</param>
        /// <param name="ScaleWidth">宽</param>
        /// <param name="ScaleHeight">高</param>
        /// <returns></returns>
        public static Image ComPressJPEG(Image ScaleImage, int ScaleWidth, int ScaleHeight)
        {
            //计算图片的缩放比例，保证图片的长宽比不变
            float Scale = Math.Min((float)ScaleWidth / ScaleImage.Width,
                (float)ScaleHeight / ScaleImage.Height);
            float newImgWidth = Scale * ScaleImage.Width;
            float newImgHeight = Scale * ScaleImage.Height;

            //当原图比需要的图小时以BackGroundColor填充
            Bitmap OutputBitmap = new Bitmap(ScaleWidth, ScaleHeight);

            Graphics g = Graphics.FromImage(OutputBitmap);
            // g.Clear(System.Drawing.Color.a)
            // g.Clear(System.Drawing.Color.Transparent);
            g.Clear(System.Drawing.Color.White);


            if (Scale > 1)
                g.DrawImage(ScaleImage,
                    (ScaleWidth - ScaleImage.Width) / 2,
                    (ScaleHeight - ScaleImage.Height) / 2,
                    ScaleImage.Width, ScaleImage.Height);
            else
                g.DrawImage(ScaleImage,
                    (ScaleWidth - newImgWidth) / 2,
                    (ScaleHeight - newImgHeight) / 2,
                    newImgWidth, newImgHeight);

            g.Dispose();
            try
            {
                EncoderParameter p;
                EncoderParameters ps;

                ps = new EncoderParameters(1);
                long[] quality = new long[1];
                quality[0] = 20;
                p = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, quality);
                ps.Param[0] = p;
                MemoryStream OutputStream = new MemoryStream();
                OutputBitmap.Save(OutputStream, GetCodecInfo("image/jpeg"), ps);
                return Image.FromStream(OutputStream);
            }
            catch (Exception ee)
            {
                throw new ApplicationException(ee.Message.ToString());
            }
        }

        #endregion

        #region MyRegion


        /// </summary>
        /// 
        /// <summary>
        /// 把一个图片加到另一个上
        /// </summary>
        /// <param name="BackGroundImage">背景图</param>
        /// <param name="img">新图</param>
        /// <param name="X">X</param>
        /// <param name="Y">Y</param>
        /// <param name="Width">宽度</param>
        /// <param name="Height">高度</param>
        public static Image DrawImage(Image BackGroundImage, Image img, int X, int Y, int Width, int Height)
        {
            Bitmap bm = new Bitmap(BackGroundImage);
            Graphics g = Graphics.FromImage(bm);

            //设置图像的透明度
            float[][] ptsArray ={
                                    new float[] {1, 0, 0, 0, 0},
                                    new float[] {0, 1, 0, 0, 0},
                                    new float[] {0, 0, 1, 0, 0},
                                    new float[] {0, 0, 0, 1, 0}, //注意：在此处设图象的透明度
                                    new float[] {0, 0, 0, 0, 1}};

            ColorMatrix clrMatrix = new ColorMatrix(ptsArray);
            ImageAttributes imgAttributes = new ImageAttributes();

            imgAttributes.SetColorMatrix(clrMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);


            g.DrawImage(img, new Rectangle(X, Y, Width, Height),
                0, 0, img.Width, img.Height,
                GraphicsUnit.Pixel, imgAttributes);
            g.Flush();
            g.Dispose();
            return bm;
        }

              #endregion

        #region 最新图片处理
        /// <summary>
        /// 获取网络上的图片，转换成2进制流
        /// </summary>
        /// <param name="Url"></param>
        /// <returns></returns>
        public static Bitmap GetUrlImage(string Url)
        {
            Bitmap img = null;
            HttpWebRequest req;
            HttpWebResponse res = null;
            try
            {
                System.Uri httpUrl = new System.Uri(Url);
                req = (HttpWebRequest)(WebRequest.Create(httpUrl));
                req.Timeout = 180000; //设置超时值10秒
                //req.UserAgent = "XXXXX";
                //req.Accept = "XXXXXX";
                req.Method = "GET";
                res = (HttpWebResponse)(req.GetResponse());
                img = new Bitmap(res.GetResponseStream());//获取图片流     
                //img.Save(@"E:/" + DateTime.Now.ToFileTime().ToString() + ".png");//随机名
            }

            catch (Exception ex)
            {
                string aa = ex.Message;
            }
            finally
            {
                res.Close();
            }
            return img;
        }

        #endregion

    }

}
